package cn.edu.zhku.controller;

import cn.edu.zhku.aspect.annotation.*;
import cn.edu.zhku.aspect.enmu.DataType;
import cn.edu.zhku.constant.ResponseCode;
import cn.edu.zhku.dto.GroupDto;
import cn.edu.zhku.dto.TaskDto;
import cn.edu.zhku.dto.UserDto;
import cn.edu.zhku.pojo.Group;
import cn.edu.zhku.pojo.Task;
import cn.edu.zhku.pojo.User;
import cn.edu.zhku.service.GroupService;
import cn.edu.zhku.swagger.notes.GroupApiNotes;
import cn.edu.zhku.util.PojoUtil;
import cn.edu.zhku.util.ResultUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import io.swagger.annotations.ApiOperation;
import org.apache.shiro.authz.annotation.RequiresPermissions;
import org.apache.shiro.authz.annotation.RequiresRoles;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.Date;
import java.util.List;

@RestController
@RequestMapping("/api/group")
public class GroupController {

    @Autowired
    private GroupService groupService;

    @RequiresPermissions("group:get")
    @CheckDataExist("没有查到群组相关信息")
    @GetMapping("/{groupId}")
    @ApiOperation("获取群组的基本信息")
    public JSONObject getGroup(@PathVariable Integer groupId) {
        Group group = this.groupService.findById(groupId);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回群组的基本信息", group);
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:add")
    @PostMapping("/add")
    @SetUserId
    @ApiOperation(value = "教师端添加群组", notes = GroupApiNotes.addGroup)
    public JSONObject addGroup(@RequestBody GroupDto groupDto) {
        this.groupService.addOne(groupDto.getGroup());
        return ResultUtil.getResult(ResponseCode.ok, "创建群组成功");
    }

    @RequiresRoles("student")
    @RequiresPermissions("group:join")
    @SetUserId
    @PostMapping("/join")
    @ApiOperation(value = "学生端加入群组", notes = GroupApiNotes.joinGroup)
    public JSONObject joinGroup(@RequestBody GroupDto groupDto) {
        String inviteCode = groupDto.getInviteCode();
        Group group = this.groupService.findByInviteCode(inviteCode);
        if (group == null)
            return ResultUtil.getResult(ResponseCode.conflict, "群组不存在");
        Integer userId = groupDto.getUserId();
        if (this.groupService.checkGroupExistByStuIdAndInviteCode(userId, inviteCode))
            return ResultUtil.getResult(ResponseCode.conflict, "请勿重复加入群组");
        if (group.getForbidden() == 1)
            return ResultUtil.getResult(ResponseCode.conflict, "禁止加入该群组");
        this.groupService.addOne2UserGroup(userId, inviteCode, new Date());
        return ResultUtil.getResult(ResponseCode.ok, "加入群组成功");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:edit")
    @CheckGroupExist("群组不存在")
    @PatchMapping("/edit")
    @ApiOperation(value = "教师修改群组", notes = GroupApiNotes.editGroup)
    public JSONObject editGroup(@RequestBody GroupDto groupDto) {
        Group group = groupDto.getGroup();
        if (PojoUtil.group.needUpdateGroup(group)) {
            this.groupService.modifyOne(group);
            return ResultUtil.getResult(ResponseCode.ok, "修改群组成功");
        } else
            return ResultUtil.getResult(ResponseCode.ok, "群组无需修改");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:remove")
    @CheckGroupExist(value = "所选（部分）群组不存在", batch = true)
    @DeleteMapping("/removeBatch")
    @ApiOperation(value = "教师端批量删除群组", notes = GroupApiNotes.removeGroupBatch)
    public JSONObject removeGroupBatch(@RequestBody GroupDto groupDto) {
        this.groupService.removeGroupBatch(groupDto.getGroupIds());
        return ResultUtil.getResult(ResponseCode.ok, "移除所选群组成功");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:remove")
    @CheckGroupExist("群组不存在")
    @DeleteMapping("/remove")
    @ApiOperation(value = "教师端删除单个群组", notes = GroupApiNotes.removeGroup)
    public JSONObject removeGroup(@RequestBody GroupDto groupDto) {
        this.groupService.removeGroupBatch(PojoUtil.pojo.convert2GroupIds(groupDto.getGroupId()));
        return ResultUtil.getResult(ResponseCode.ok, "移除群组成功");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:removeUser")
    @CheckGroupExist("群组不存在")
    @CheckGroupUserExist(value = "所选（部分）群成员已被移除出群组", batch = true)
    @DeleteMapping("/removeUserBatch")
    @ApiOperation(value = "教师端批量移除群成员", notes = GroupApiNotes.removeUserBatch)
    public JSONObject removeUserBatch(@RequestBody GroupDto groupDto) {
        this.groupService.removeUserBatch(groupDto.getGroupId(), groupDto.getUserIds());
        return ResultUtil.getResult(ResponseCode.ok, "移除所选群成员成功");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:removeUser")
    @CheckGroupExist("群组不存在")
    @CheckGroupUserExist("群成员已被移除出群组")
    @DeleteMapping("/removeUser")
    @ApiOperation(value = "教师端移除单个群成员", notes = GroupApiNotes.removeUser)
    public JSONObject removeUser(@RequestBody GroupDto groupDto) {
        this.groupService.removeUserBatch(groupDto.getGroupId(), PojoUtil.pojo.convert2UserIds(groupDto.getUserId()));
        return ResultUtil.getResult(ResponseCode.ok, "移除群成员成功");
    }

    @RequiresRoles("student")
    @SetUserId
    @CheckGroupExist("群组不存在")
    @CheckGroupUserExist("你已不是群成员")
    @DeleteMapping("/quit")
    @ApiOperation(value = "学生端退出群组", notes = GroupApiNotes.quit)
    public JSONObject quit(@RequestBody GroupDto groupDto) {
        this.groupService.removeUserBatch(groupDto.getGroupId(), PojoUtil.pojo.convert2UserIds(groupDto.getUserId()));
        return ResultUtil.getResult(ResponseCode.ok, "退出群组成功");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:removeTask")
    @CheckGroupExist("群组不存在")
    @CheckGroupTaskExist(value = "所选（部分）任务已被移除出群组", batch = true)
    @DeleteMapping("/removeTaskBatch")
    @ApiOperation(value = "教师端批量移除群内任务", notes = GroupApiNotes.removeTaskBatch)
    public JSONObject removeTaskBatch(@RequestBody GroupDto groupDto) {
        this.groupService.removeTaskBatch(groupDto.getGroupId(), groupDto.getTaskIds());
        return ResultUtil.getResult(ResponseCode.ok, "移除所选任务成功");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:removeTask")
    @CheckGroupExist("群组不存在")
    @CheckGroupTaskExist("任务已被移除出群组")
    @DeleteMapping("/removeTask")
    @ApiOperation(value = "教师端移除群内单个任务", notes = GroupApiNotes.removeTask)
    public JSONObject removeTask(@RequestBody GroupDto groupDto) {
        this.groupService.removeTaskBatch(groupDto.getGroupId(), PojoUtil.pojo.convert2TaskIds(groupDto.getTaskId()));
        return ResultUtil.getResult(ResponseCode.ok, "移除任务成功");
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("group:list")
    @SetUserId
    @Paging(DataType.GROUP)
    @CheckDataExist("没有查到相关群组信息")
    @PostMapping("/tea")
    @ApiOperation(value = "教师端获取群组列表", notes = GroupApiNotes.tea)
    public JSONObject tea(@RequestBody GroupDto groupDto) {
        PageHelper.startPage(groupDto.getPageNum(), groupDto.getPageSize());
        List<Group> groups = this.groupService.findGroupTea(groupDto.getGroup());
        PageInfo<Group> pageInfo = new PageInfo<>(groups);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回群组列表", pageInfo);
    }

    @RequiresRoles("student")
    @RequiresPermissions("group:list")
    @SetUserId
    @Paging(DataType.GROUP)
    @CheckDataExist("没有查到相关群组信息")
    @PostMapping("/stu")
    @ApiOperation(value = "学生端获取群组列表", notes = GroupApiNotes.stu)
    public JSONObject stu(@RequestBody GroupDto groupDto) {
        PageHelper.startPage(groupDto.getPageNum(), groupDto.getPageSize());
        List<Group> groups = this.groupService.findGroupStu(groupDto.getGroup());
        PageInfo<Group> pageInfo = new PageInfo<>(groups);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回群组列表", pageInfo);
    }

    @RequiresPermissions("user:list")
    @Paging(DataType.USER)
    @CheckDataExist("没有查到相关群成员信息")
    @PostMapping({"/tea/user", "/stu/user"})
    @ApiOperation(value = "获取群成员列表", notes = GroupApiNotes.groupUser)
    public JSONObject groupUser(@RequestBody UserDto userDto) {
        PageHelper.startPage(userDto.getPageNum(), userDto.getPageSize());
        List<User> users = this.groupService.findGroupUser(userDto);
        PageInfo<User> pageInfo = new PageInfo<>(users);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回群成员列表", pageInfo);
    }

    @RequiresRoles("teacher")
    @RequiresPermissions("task:list")
    @SetUserId
    @Paging(DataType.TASK)
    @CheckDataExist("没有查到相关任务信息")
    @PostMapping("/tea/task")
    @ApiOperation(value = "教师端获取群内任务列表", notes = GroupApiNotes.teaTask)
    public JSONObject teaTask(@RequestBody TaskDto taskDto) {
        PageHelper.startPage(taskDto.getPageNum(), taskDto.getPageSize());
        List<Task> tasks = this.groupService.findGroupTaskTea(taskDto);
        PageInfo<Task> pageInfo = new PageInfo<>(tasks);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回任务列表", pageInfo);
    }

    @RequiresRoles("student")
    @RequiresPermissions("task:list")
    @SetUserId
    @Paging(DataType.TASK)
    @CheckDataExist("没有查到相关任务信息")
    @PostMapping("/stu/task")
    @ApiOperation(value = "学生端获取群内任务列表", notes = GroupApiNotes.stuTask)
    public JSONObject stuTask(@RequestBody TaskDto taskDto) {
        PageHelper.startPage(taskDto.getPageNum(), taskDto.getPageSize());
        List<Task> tasks = this.groupService.findGroupTaskStu(taskDto);
        PageInfo<Task> pageInfo = new PageInfo<>(tasks);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回任务列表", pageInfo);
    }

    @RequiresPermissions("user:list")
    @GetMapping("/{groupId}/userNum}")
    @ApiOperation("获取某个群的群成员数")
    public JSONObject getGroupUserNum(@PathVariable Integer groupId) {
        Integer userNum = this.groupService.getGroupUserNumByGroupId(groupId);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回群内成员数", userNum);
    }

    @RequiresPermissions("task:list")
    @GetMapping("/{groupId}/taskNum")
    @ApiOperation("获取某个群的群任务数")
    public JSONObject getGroupTaskNum(@PathVariable Integer groupId) {
        Integer taskNum = this.groupService.getGroupTaskNumByGroupId(groupId);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回群内任务数", taskNum);
    }

    @RequiresPermissions("form:list")
    @GetMapping("/{groupId}/{taskId}/formNum")
    @ApiOperation("获取某个群下某个任务中的已提交表单数")
    public JSONObject getgetGroupTaskFormNum(@PathVariable Integer groupId, @PathVariable Integer taskId) {
        Integer formNum = this.groupService.getGroupTaskFormNumByGroupIdAndTaskId(groupId, taskId);
        return ResultUtil.getResult(ResponseCode.ok, "成功返回群内任务的表单提交数", formNum);
    }

}
